//package indi.zhifa.core.redis.filtter;
//
//
//
//import indi.zhifa.core.common.web.entity.exception.ServiceException;
//import indi.zhifa.core.redis.ann.RedissonLock;
//import lombok.AllArgsConstructor;
//import lombok.RequiredArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.redisson.api.RLock;
//import org.redisson.api.RedissonClient;
//import org.springframework.expression.EvaluationContext;
//import org.springframework.expression.spel.standard.SpelExpressionParser;
//import org.springframework.expression.spel.support.StandardEvaluationContext;
//import org.springframework.stereotype.Component;
//
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.List;
//import java.util.concurrent.TimeUnit;
//
//@RequiredArgsConstructor
//@Aspect
//@Slf4j
//@Component
//public class RedissonHandler {
//    private final RedissonClient mRedissonClient;
//
//    @Around("@annotation(pRedissonConfig)")
//    public Object around(ProceedingJoinPoint joinPoint, RedissonLock pRedissonConfig) throws Throwable {
//        String prefix = pRedissonConfig.prefix();
//
//        List<String> keys = new ArrayList<>();
//        for(String keyExp : pRedissonConfig.keys()){
//            String key = prefix+doKey(joinPoint,keyExp);
//            keys.add(key);
//        }
//        List<RLock> rLocks = new ArrayList<>();
//        for(String key : keys){
//            RLock rLock = mRedissonClient.getLock(key);
//            rLocks.add(rLock);
//        }
//
//        for(int i=0;i<keys.size();i++){
//            RLock rLock = rLocks.get(i);
//            String key = keys.get(i);
//            if(pRedissonConfig.leaseTime() > 0){
//                // 不加看门狗
//                try{
//                    if(pRedissonConfig.waitTime() > 0L){
//                        boolean ret = rLock.tryLock(pRedissonConfig.waitTime(), pRedissonConfig.leaseTime(), TimeUnit.SECONDS);
//                        if(!ret){
//                            throw new ServiceException(key+" 上锁失败，请联系管理员");
//                        }
//                    }else{
//                        rLock.lock(pRedissonConfig.leaseTime(),TimeUnit.SECONDS);
//                    }
//
//                }catch (InterruptedException interruptedException){
//                    throw new ServiceException(key+" 上锁失败，失败信息是 "+interruptedException+"请联系管理员");
//                }
//
//            }else{
//                // 加看门狗
//                if(pRedissonConfig.waitTime() > 0L){
//                    boolean ret = rLock.tryLock(pRedissonConfig.waitTime(), TimeUnit.SECONDS);
//                    if(!ret){
//                        throw new ServiceException(key+" 上锁失败，请联系管理员");
//                    }
//                }else{
//                    rLock.lock();
//                }
//            }
//        }
//
//        Object ret = null;
//        try{
//            ret = joinPoint.proceed(joinPoint.getArgs());
//        }catch (Exception ex){
//            throw ex;
//        }finally {
//            try{
//                for(RLock rLock : rLocks){
//                    rLock.unlock();
//                }
//            }catch (Exception ex){
//                log.error("解锁超时");
//            }
//        }
//        return ret;
//    }
//
//    public String doKey(ProceedingJoinPoint joinPoint, String key) {
//        //获取方法的参数名和参数值
//        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//        List<String> paramNameList = Arrays.asList(methodSignature.getParameterNames());
//        List<Object> paramList = Arrays.asList(joinPoint.getArgs());
//
//        //将方法的参数名和参数值一一对应的放入上下文中
//        EvaluationContext ctx = new StandardEvaluationContext();
//        for (int i = 0; i < paramNameList.size(); i++) {
//            ctx.setVariable(paramNameList.get(i), paramList.get(i));
//        }
//
//        SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
//        // 解析SpEL表达式获取结果
//        String value = spelExpressionParser.parseExpression(key).getValue(ctx).toString();
//        return value;
//    }
//}
